package com.lam.generator.entity;

import java.util.Date;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.lam.common.base.domain.BaseEntity;
import com.lam.common.components.dict.annotation.Dict;
import com.lam.common.constant.CommonConstant;
import com.lam.common.utils.CollectionUtil;
import com.lam.common.utils.DateUtil;
import com.lam.common.utils.NumberUtil;
import com.lam.common.utils.StringUtils;
import com.lam.generator.common.constant.GeneratorConstant;
import com.lam.generator.common.util.GenUtils;

/**
 * 代码生成字段对象 gen_table_column
 * 
 * @author admin
 * @date 2022-09-26
 */
@TableName("gen_table_column")
public class GenTableColumn implements BaseEntity{

    /** 主键 */
    @TableId(type = IdType.AUTO)
    private String id;
    
    /** 归属表编号 */
    @NotBlank(message = "归属表编号不能为空")
    @Size(max = 64, message = "归属表编号长度不能超过64个字符")
    private String tableId;

    /** 列名称 */
    @NotBlank(message = "列名称不能为空")
    @Size(max = 200, message = "列名称长度不能超过200个字符")
    private String columnName;

    /** 列描述 */
    @Size(max = 500, message = "列描述长度不能超过500个字符")
    private String columnComment;

    /** 列类型 */
    @NotBlank(message = "列类型不能为空")
    @Size(max = 100, message = "列类型长度不能超过100个字符")
    private String columnType;

    /** 列长度 */
    private Long columnLength;

    /** JAVA类型 */
    @NotBlank(message = "JAVA类型不能为空")
    @Size(max = 500, message = "JAVA类型长度不能超过500个字符")
    private String javaType;

    /** JAVA字段长度 */
    private Long javaLength;

    /** JAVA字段名 */
    @NotBlank(message = "JAVA字段名不能为空")
    @Size(max = 200, message = "JAVA字段名长度不能超过200个字符")
    private String javaField;

    /** JAVA字段描述 */
    @Size(max = 300, message = "JAVA字段描述长度不能超过300个字符")
    private String javaFieldDesc;

    /** 界面表单项名称 */
    @Size(max = 300, message = "界面表单项名称长度不能超过300个字符")
    private String formItemLabel;

    /** 是否主键（1是） */
    @Dict(dictCode = "yn10")
    private Integer isPk;

    /** 是否自增（1是） */
    @Dict(dictCode = "yn10")
    private Integer isIncrement;

    /** 是否必填（1是） */
    @Dict(dictCode = "yn10")
    private Integer isRequired;

    /** 是否编辑字段（1是） */
    @Dict(dictCode = "yn10")
    private Integer isEdit;

    /** 是否列表字段（1是） */
    @Dict(dictCode = "yn10")
    private Integer isList;

    /** 是否查询字段（1是） */
    @Dict(dictCode = "yn10")
    private Integer isQuery;

    /** 查询方式（EQ等于、NE不等于、GT大于、LT小于、LIKE模糊、BETWEEN范围） */
    @Size(max = 200, message = "查询方式长度不能超过200个字符")
    @Dict(dictCode = "queryType")
    private String queryType;

    /** 显示类型（input文本框、textarea文本域、select下拉框、checkbox复选框、radio单选框、date日期控件、datetime日期时间控件） */
    @Size(max = 200, message = "显示类型长度不能超过200个字符")
    @Dict(dictCode = "htmlType")
    private String htmlType;

    /** 字典编码 */
    @Size(max = 200, message = "字典编码长度不能超过200个字符")
    private String dictCode;

    /** 新增字典编码内容 */
    @Size(max = 500, message = "新增字典编码内容长度不能超过500个字符")
    private String dictText;

    /** 排序 */
    private Integer sort;

    /** 创建人 */
    private String createBy;

    /** 创建时间 */
    @JsonFormat(pattern = DateUtil.PATTERN_DEFAULT)
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    /** 修改人 */
    private String updateBy;

    /** 修改时间 */
    @JsonFormat(pattern = DateUtil.PATTERN_DEFAULT)
    @TableField(fill = FieldFill.UPDATE)
    private Date updateTime;
    
    /** 是否父类字段（1是） */
    @TableField(exist = false)
	private boolean superColumn;
    /** 是否唯一字段（1是） */
    @TableField(exist = false)
	private boolean unique;
	
	public static GenTableColumn create(DbTableColumn dbColumn) {
		GenTableColumn genColumn = new GenTableColumn();
		genColumn.setColumnName(dbColumn.getColumnName());
		genColumn.setColumnComment(dbColumn.getColumnComment());
		genColumn.setColumnType(dbColumn.getColumnType());
		genColumn.setColumnLength(dbColumn.getColumnLength());
		genColumn.setIsPk(dbColumn.getIsPk());
		genColumn.setIsIncrement(dbColumn.getIsIncrement());
		genColumn.setIsRequired(dbColumn.getIsRequired());
		genColumn.setSort(dbColumn.getSort());
		return genColumn;
	}
	
	public boolean merge(DbTableColumn dbColumn) {
		if(dbColumn.getSort() !=null) {
			sort = dbColumn.getSort();
		}
		if(dbColumn.getIsIncrement() != null) {
			isIncrement = dbColumn.getIsIncrement();
		}
		if(dbColumn.getIsRequired() != null) {
			isRequired = dbColumn.getIsRequired();
		}
		if(dbColumn.getIsPk() != null) {
			isPk = dbColumn.getIsPk();
		}
		
		boolean flag = false;
		if(StringUtils.isNotBlank(dbColumn.getColumnComment()) && !StringUtils.equals(columnComment, dbColumn.getColumnComment())) {
			columnComment = dbColumn.getColumnComment();
			String cm = columnComment.replace("（", "(").replace("）", ")");
			if(cm.contains("(") && cm.contains(")")) {
				flag = true;
			}
		}
		if(StringUtils.isNotBlank(dbColumn.getColumnType()) && !StringUtils.equals(columnType, dbColumn.getColumnType())) {
			columnType = dbColumn.getColumnType();
			flag = true;
		}
		if(!NumberUtil.eq(dbColumn.getColumnLength(), columnLength)) {
			columnLength = dbColumn.getColumnLength();
			flag = true;
		}
		return flag;
	}
	
	public String getAttrName() {
		if(javaField.length() > 2 && javaField.substring(1,2).matches("[A-Z]")) {
			return javaField;
		}
		return javaField.substring(0,1).toUpperCase() + javaField.substring(1);
	}
	
	/**
	 * xml中的筛选条件
	 * @return
	 */
	public String getQueryCondition() {
		
		String fmt = "%s #{%s}";
		switch (queryType.toUpperCase()) {
		case "EQ":return String.format(fmt, "=", javaField);
		case "NE":return String.format(fmt, "!=", javaField);
		case "GT":return String.format(fmt, "<![CDATA[>]]>", javaField);
		case "GTE":return String.format(fmt, "<![CDATA[>=]]>", javaField);
		case "LT":return String.format(fmt, "<![CDATA[<]]>", javaField);
		case "LTE":return String.format(fmt, "<![CDATA[<=]]>", javaField);
		case "LIKE":return String.format("like concat('%%', #{%sKey}, '%%')", javaField);
		default:
			return String.format(fmt, "=", javaField);
		}
	}
	
	public boolean isBaseParamColumn() {
		// BaseParam
		return StringUtils.equalsAnyIgnoreCase(javaField, "createBy", "updateBy", "beginTime", "endTime", "id");
	}
	
	public String convertDesc(){
		if(StringUtils.isBlank(this.columnComment)){
			return "";
		}
		if(columnComment.contains("（")){
			return columnComment.substring(0, columnComment.indexOf('（'));
		}
		if(this.columnComment.contains("(")){
			return columnComment.substring(0, columnComment.indexOf('('));
		}
		if(this.columnComment.contains("[")){
			return columnComment.substring(0, columnComment.indexOf('['));
		}
		return this.columnComment;
	}

	public String readConverterExp() {
		if(StringUtils.isBlank(this.columnComment)){
			return "";
		}
		
		String comment = this.columnComment.replace("（", "(").replace("）", ")").replace("[", "(").replace("]", ")");
		String remarks = StringUtils.substringBetween(comment, "(", ")");
		if (StringUtils.isBlank(remarks)) {
			return "";
		}
		
		remarks = remarks.replace(" ", ",").replace("，", ",");
		if(!remarks.trim().contains(",")){
			return "";
		}
		
		StringBuilder sb = new StringBuilder();
		for (String value : remarks.split(",")) {
			if (StringUtils.isNotBlank(value)) {
				value = StringUtils.trim(value);
				if(value.length() > 1){
					if(value.contains("-")) {
						String[] vv = value.split("-");
						sb.append(String.format("%s=%s,", StringUtils.trim(vv[0]), StringUtils.trim(vv[1])));
					}else {
						sb.append(String.format("%s=%s,", value.subSequence(0, 1), value.substring(1)));
					}
				}else{
					sb.append(String.format("%s=%s,", value, value));
				}
			}
		}
		return sb.deleteCharAt(sb.length() - 1).toString();
	}

	public void setTableId(String tableId) {
		this.tableId = tableId;
	}

	public String getTableId() {
		return tableId;
	}

	public void setColumnName(String columnName) {
		this.columnName = columnName;
	}

	public String getColumnName() {
		return columnName;
	}

	public void setColumnComment(String columnComment) {
		this.columnComment = columnComment;
	}

	public String getColumnComment() {
		return columnComment;
	}

	public void setColumnType(String columnType) {
		this.columnType = columnType;
	}

	public String getColumnType() {
		return columnType;
	}
	
	public String getDataType() {
		return GenUtils.getDbType(columnType);
	}
	
	/**
	 * 是否真的字符串类型
	 * @return
	 */
	public boolean isStrDataType() {
		return CollectionUtil.contains(GeneratorConstant.COLUMNTYPE_STR_WITH_NO_LENGTH, getDataType())
				|| (CollectionUtil.contains(GeneratorConstant.COLUMNTYPE_STR_WITH_LENGTH, getDataType()) 
						&& columnLength > 2);
	}

	public void setJavaType(String javaType) {
		this.javaType = javaType;
	}

	public String getJavaType() {
		return javaType;
	}

	public void setJavaField(String javaField) {
		this.javaField = javaField;
	}

	public String getJavaField() {
		return javaField;
	}

	public void setIsPk(Integer isPk) {
		this.isPk = isPk;
	}

	public Integer getIsPk() {
		return isPk;
	}

	public boolean isPk() {
		return isYes(this.isPk);
	}
	
	public boolean isYes(Integer v) {
		return NumberUtil.eq(CommonConstant.YES1, v);
	}

	public Integer getIsIncrement() {
		return isIncrement;
	}

	public void setIsIncrement(Integer isIncrement) {
		this.isIncrement = isIncrement;
	}

	public boolean isIncrement() {
		return isYes(this.isIncrement);
	}

	public void setIsRequired(Integer isRequired) {
		this.isRequired = isRequired;
	}

	public Integer getIsRequired() {
		return isRequired;
	}

	public boolean isRequired() {
		return isYes(this.isRequired);
	}

	public void setIsEdit(Integer isEdit) {
		this.isEdit = isEdit;
	}

	public Integer getIsEdit() {
		return isEdit;
	}

	public boolean isEdit() {
		return isYes(this.isEdit);
	}

	public void setIsList(Integer isList) {
		this.isList = isList;
	}

	public Integer getIsList() {
		return isList;
	}

	public boolean isList() {
		return isYes(this.isList);
	}

	public void setIsQuery(Integer isQuery) {
		this.isQuery = isQuery;
	}

	public Integer getIsQuery() {
		return isQuery;
	}

	public boolean isQuery() {
		return isYes(this.isQuery);
	}

	public void setQueryType(String queryType) {
		this.queryType = queryType;
	}

	public String getQueryType() {
		return queryType;
	}

	public void setDictCode(String dictCode) {
		this.dictCode = dictCode;
	}

	public String getDictCode() {
		return dictCode;
	}

	public void setSort(Integer sort) {
		this.sort = sort;
	}

	public Integer getSort() {
		return sort;
	}

	public String getDictText() {
		return dictText;
	}

	public void setDictText(String dictText) {
		this.dictText = dictText;
	}

	public String getHtmlType() {
		return htmlType;
	}

	public void setHtmlType(String htmlType) {
		this.htmlType = htmlType;
	}

	public String getJavaFieldDesc() {
		return javaFieldDesc;
	}

	public void setJavaFieldDesc(String javaFieldDesc) {
		this.javaFieldDesc = javaFieldDesc;
	}

	public String getFormItemLabel() {
		return formItemLabel;
	}

	public void setFormItemLabel(String formItemLabel) {
		this.formItemLabel = formItemLabel;
	}

	public boolean isSuperColumn() {
		return superColumn;
	}

	public void setSuperColumn(boolean superColumn) {
		this.superColumn = superColumn;
	}

	public Long getJavaLength() {
		return javaLength;
	}

	public void setJavaLength(Long javaLength) {
		this.javaLength = javaLength;
	}

	public Long getColumnLength() {
		return columnLength;
	}

	public void setColumnLength(Long columnLength) {
		this.columnLength = columnLength;
	}

	public String getCreateBy() {
		return createBy;
	}

	public void setCreateBy(String createBy) {
		this.createBy = createBy;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	public String getUpdateBy() {
		return updateBy;
	}

	public void setUpdateBy(String updateBy) {
		this.updateBy = updateBy;
	}

	public Date getUpdateTime() {
		return updateTime;
	}

	public void setUpdateTime(Date updateTime) {
		this.updateTime = updateTime;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public boolean isUnique() {
		return unique;
	}

	public void setUnique(boolean unique) {
		this.unique = unique;
	}

}
